// 编译
// tsc 文件名
// tsc --outFile 输出目录 待转化文件


// 参数后冒号设定接收类型
// 类型首字母均为小写
function helloWorld(content: string) {
    console.log("hello")
    console.log(content)
}


// 布尔类型
// 构造函数new创建的是 布尔对象 ，不是 布尔值
let isDone: boolean = true
// 不能将类型“Boolean”分配给类型“boolean”。
// “boolean”是基元，但“Boolean”是包装器对象。
// 错误表达：let isDone2:boolean = new Boolean(1)
let isDone2: boolean = Boolean(1)


// 数值类型
let num: number = 5
let nonum: number = NaN
let infint: number = Infinity


// 字符串
let str: string = "abc"
let str1: string = `i am ${str}`


// 箭头函数
let add = (a: number, b: number): number => a + b //最后设定返回值类型


// 没有返回值
function say(name: string): void { //最后设定返回值类型
    console.log(name)
    // return true 报错
}


// void类型只能是null或undefined
let value: void
value = null
value = undefined
// value = 0 报错


// null和undefined可互换,也是所有类型的子类型
let a: undefined = undefined
let b: null = null
a = null
b = undefined


// 任意值
let anyType: any = "hi"
anyType = 5
// 隐式any类型
let dog
dog = "狗"
dog = 111
// 声明时未指定类型,则按赋值的类型推断
let oneType = "hi"
// oneType = 5 报错


// 联合类型
let combine: string | number = "string"
combine = 1
// 只能调用共有属性
// combine.length 报错
combine.toString()


// 接口，关键字：interface
// 接口用于定义对象的类型
interface Person {
    readonly name: string; //只读
    age: number;
    gender?: string; //? 表示 可选属性
    [propName: string]: any; //添加任意属性
}
let tom: Person = {
    name: 'abc',
    age: 16,
    test: "test",
}
// tom.name = "aaa" 报错


// 数组方式1
let arr1: number[] = [1, 2, 3]
let arr2: string[] = ['af', 'sdf']
let arr4: any[] = [1, 'sdf', {}]
// 数组方式2
let arr11: Array<number> = [1, 2, 3]
// 数组方式3
interface NumberArr {
    [index: number]: number;
}
let arr3: NumberArr = [1, 2, 3]
// 类数组
function abc() {
    let args: {
        [index: number]: number,
        length: number
    } = arguments
}
// 系统提供的类数组
function abc2() {
    let args: IArguments = arguments
}


// 函数1
interface searchFn {
    // 参数用括号包裹
    (keyword: string, type: number, choose?: string): string
}
let mySearch: searchFn = function (keyword, type) {
    return "string"
}
mySearch("ffe", 0, "choose")

// 函数2
function calculate(type: string, ...items: number[]): number {
    if (type == "add") {
        return items.reduce((pre, item) => {
            return pre + item
        })
    } else {
        return items.reduce((pre, item) => {
            return pre * item
        })
    }
}
calculate("add", 1, 2, 3, 4, 5)
calculate("mul", 1, 5, 6, 7)

// 函数3
// 重载定义
function abcd(x: number): number;
function abcd(x: string): string;
function abcd(x: string | number): string | number {
    // 输入number返回number，输入string返回string
    if (typeof x == "number") {
        return x + 666
    } else if (typeof x == "string") {
        return "stirng:" + x
    }
}

// 设置默认值的函数
function printName(first: string = "西门", last: string = "吹雪"): string {
    return first + last
}